﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Utilities;

namespace PayexpDAL
{
    public partial class TransactionMasterChequeDetail
    {
        [NonSerialized]
        private byte[] _fileContent;

        public byte[] FileContent
        {
            get { return _fileContent; }
            set 
            { 
                _fileContent = value;
                if (_fileContent != null)
                {
                    _fileContentChanged = true;
                }
                else
                {
                    _fileContentChanged = false;
                }
            }
        }

        [NonSerialized]
        private bool _fileContentChanged;

        public bool FileContentChanged
        {
            get { return _fileContentChanged; }
            set { _fileContentChanged = value; }
        }

        public string BankDisplayName
        {
            get
            {
                if (SettingsAndStaticListLoader.StaticListMap.ContainsKey(Constants.TableConstants.StaticListConstants.bankname))
                {
                    var bankNameValue = SettingsAndStaticListLoader.StaticListMap[Constants.TableConstants.StaticListConstants.bankname].
                                        Where(t => t.ListItemCode.Equals(this.ChequeDrawnOnBank)).FirstOrDefault();

                    if (bankNameValue != null)
                    {
                        return bankNameValue.ListItemValue;
                    }
                    else
                    {
                        return this.ChequeDrawnOnBank;
                    }
                }
                else
                {
                    return this.ChequeDrawnOnBank;
                }
            }
        }
    }

    public partial class BankAccount
    {
        public decimal AvailableBalance
        {
            get;
            set;
        }

        public decimal ReonciledBalance
        {
            get;
            set;
        }
        
        public string BankDisplayName
        {
            get
            {
                if (SettingsAndStaticListLoader.StaticListMap.ContainsKey(Constants.TableConstants.StaticListConstants.bankname))
                {
                    var bankNameValue = SettingsAndStaticListLoader.StaticListMap[Constants.TableConstants.StaticListConstants.bankname].
                                        Where(t => t.ListItemCode.Equals(this.BankName)).FirstOrDefault();

                    if (bankNameValue != null)
                    {
                        return bankNameValue.ListItemValue;
                    }
                    else
                    {
                        return this.BankName;
                    }
                }
                else
                {
                    return this.BankName;
                }
            }
        }

        public DateTime? EarliestBankDateTimeInCurrentFY
        {
            get;
            set;
        }

        public DateTime? LatestBankDateTimeInCurrentFY
        {
            get;
            set;
        }
    }

    public partial class TransactionMaster
    {
        public TransactionMaster Clone()
        {
            TransactionMaster clone = new TransactionMaster();
            clone.Id = 0;
            clone.BankAccountsId = this.BankAccountsId;
            clone.VoucherReceiptPrefix = this.VoucherReceiptPrefix;
            clone.Head = this.Head;
            clone.TransactionModeValue = this.TransactionModeValue;
            clone.TransactionDate = this.TransactionDate;
            clone.BankDate = this.BankDate;
            clone.TransactionAmount = this.TransactionAmount;
            clone.InvoiceOrBillNumber = this.InvoiceOrBillNumber;
            clone.PONumber = this.PONumber;
            clone.Narration = this.Narration;
            clone.HeadDetailsLeafId = this.HeadDetailsLeafId;
            clone.HeadDetailsHierarchyIdList = this.HeadDetailsHierarchyIdList;
            clone.PettyCashIdList = this.PettyCashIdList;
            clone.VoucherReceiptPrintedOn = this.VoucherReceiptPrintedOn;
            clone.IsActive = true;

            foreach (TransactionMasterChequeDetail transactionMasterChequeDetail in this.TransactionMasterChequeDetails)
            {
                TransactionMasterChequeDetail clonedChequeDetails = new TransactionMasterChequeDetail();
                clonedChequeDetails.Id = 0;
                clonedChequeDetails.ChequeNumber = transactionMasterChequeDetail.ChequeNumber;
                clonedChequeDetails.ChequeDate = transactionMasterChequeDetail.ChequeDate;
                clonedChequeDetails.ChequeAmount = transactionMasterChequeDetail.ChequeAmount;
                clonedChequeDetails.ChequeDrawnOnBank = transactionMasterChequeDetail.ChequeDrawnOnBank;
                clonedChequeDetails.ChequeStatus = transactionMasterChequeDetail.ChequeStatus;
                clonedChequeDetails.ScannedChequeImagePath = transactionMasterChequeDetail.ScannedChequeImagePath;
                clonedChequeDetails.Narration = transactionMasterChequeDetail.Narration;
                clonedChequeDetails.IsActive = true;
                clone.TransactionMasterChequeDetails.Add(clonedChequeDetails);
            }


            return clone;
        }

        public decimal RollOverAmount
        {
            get;
            set;
        }
        
        private string _buildingName = string.Empty;

        public string BuildingName
        {
            get 
            {
                SetBuildingNameAndFlatNumber();
                return _buildingName; 
            }
            
        }

        private string _flatNumber = string.Empty;

        public string FlatNumber
        {
            get 
            {
                SetBuildingNameAndFlatNumber();
                return _flatNumber; 
            }
            
        }

        public string ExpenseApprovalDetails
        {
            get
            {
                string details = this.ExpenseApproverNames;
                if (string.IsNullOrEmpty(details))
                {
                    if (this.Head.Equals("head_expense") && this.IsAutoApproved)
                    {
                        details = "Auto Approved";
                    }
                    else
                    {
                        details = "Approval not required";
                    }
                }
                return details;
            }
        }

        private string ExpenseApproverNames
        {
            get
            {
                string names = string.Empty;
                if (!string.IsNullOrEmpty(this.ExpenseApproverIdList))
                {
                    List<int> approverIdList = this.ExpenseApproverIdList.GetIntegerListFromSquareBracketedCommaSeparatedString();
                    if (approverIdList.Count == 0)
                    {
                        return string.Empty;
                    }
                    List<ExpenseApprover> requiredList = SettingsAndStaticListLoader.ExpenseApproverList.Where(t => approverIdList.Contains(t.Id)).ToList();
                    names = string.Join(", ", requiredList.Select(t => t.FirstName).ToArray());
                }
                return names;
            }
        }

        private void SetBuildingNameAndFlatNumber()
        {
            List<TransactionType> transactionTypeList = GetTransactionTypes();
            
            // HARDCODING THIS FOR NOW. BUT, NEED TO MOVE IT TO CONFIG OR THE DATABASE
            // Maintenance Charges node id = 6
            if(transactionTypeList.Any(t => t.Id.Equals(6)))
            {
                this._buildingName = "Not selected properly";
                this._flatNumber = "Not selected properly";

                transactionTypeList.RemoveAt(0); // removing the root node i.e. "Income"

                if (transactionTypeList.Count > 0)
                {
                    transactionTypeList.RemoveAt(0); // removing the node with id 6 i.e. Maintenance Charges
                }

                if (transactionTypeList.Count > 0)
                {
                    this._buildingName = transactionTypeList[0].Name.ToLower().Replace("building", string.Empty).ToUpper().Trim();
                    transactionTypeList.RemoveAt(0);
                }

                if (transactionTypeList.Count > 0)
                {
                    this._flatNumber = transactionTypeList[0].Name;
                }
            }
        }

        private List<TransactionType> GetTransactionTypes()
        {
            string[] idList = this.HeadDetailsHierarchyIdList.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

            List<int> transTypeIdList = new List<int>();
            foreach (string id in idList)
            {
                // CHECK THIS CHANGE
                string idWithoutBrackets = id.Replace("[", string.Empty).Replace("]", string.Empty).Trim();
                //transTypeIdList.Add(int.Parse(id));
                transTypeIdList.Add(int.Parse(idWithoutBrackets));
            }

            List<TransactionType> transactionTypeList = new DataAccessHandler().GetTransactionTypeListByIdList(transTypeIdList, new AlfaRomeoEntities());
            transactionTypeList = ArrangeItems(transactionTypeList);

            return transactionTypeList;
        }
        

        public string GetHeadDetailsComplete()
        {
            List<TransactionType> transactionTypeList = GetTransactionTypes();
            if (transactionTypeList.Count > 0)
            {
                transactionTypeList.RemoveAt(0);
                string headDetailsComplete = string.Join("-->", transactionTypeList.Select(t => t.Name).ToArray());
                return headDetailsComplete;
            }
            else
            {
                return string.Empty;
            }
        }

        public string GetConsolidatedChequeDetails()
        {
            string consolidatedDetails = string.Empty;

            string format = "No: {0}, Dated: {1}, {2}";
            List<string> temp = new List<string>();

            foreach (var transactionMasterChequeDetails in this.TransactionMasterChequeDetails)
            {
                temp.Add(string.Format(format, transactionMasterChequeDetails.ChequeNumber,
                                        transactionMasterChequeDetails.ChequeDate.Get_DD_MONTH_YY_DateString(),
                                        transactionMasterChequeDetails.BankDisplayName));
            }

            if (temp.Count > 0)
            {
                consolidatedDetails = string.Join(Environment.NewLine, temp.ToArray());
            }

            return consolidatedDetails;
        }

        public string ConsolidateChequeDetails
        {
            get
            {
                return GetConsolidatedChequeDetails();
            }
        }

        public string HeadDetailsDisplayName
        {
            get
            {
                return GetHeadDetailsComplete();
            }
        }

        public string TransactionDateDDMonthYY
        {
            get
            {
                return this.TransactionDate.Get_DD_MONTH_YY_DateString();
            }
        }

        public string HeadDisplayName
        {
            get
            {
                if (SettingsAndStaticListLoader.StaticListMap.ContainsKey(Constants.TableConstants.StaticListConstants.head))
                {
                    var headValue = SettingsAndStaticListLoader.StaticListMap[Constants.TableConstants.StaticListConstants.head].
                                        Where(t => t.ListItemCode.Equals(this.Head)).FirstOrDefault();

                    if (headValue != null)
                    {
                        return headValue.ListItemValue;
                    }
                    else
                    {
                        return this.Head;
                    }
                }
                else
                {
                    return this.Head;
                }
            }
        }

        public string TransactionModeValueDisplayName
        {
            get
            {
                if (SettingsAndStaticListLoader.StaticListMap.ContainsKey(Constants.TableConstants.StaticListConstants.transactionmode))
                {
                    var transactionMode = SettingsAndStaticListLoader.StaticListMap[Constants.TableConstants.StaticListConstants.transactionmode].
                                        Where(t => t.ListItemCode.Equals(this.TransactionModeValue)).FirstOrDefault();

                    if (transactionMode != null)
                    {
                        return transactionMode.ListItemValue;
                    }
                    else
                    {
                        return this.TransactionModeValue;
                    }
                }
                else
                {
                    return this.TransactionModeValue;
                }
            }
        }

        public decimal CurrentBalance
        {
            get;
            set;
        }

        public string ChequeDrawnOnBank
        {
            get
            {
                if (this.TransactionMasterChequeDetails.Count > 0) // can always be just one
                {
                    return this.TransactionMasterChequeDetails.FirstOrDefault().BankDisplayName;
                }
                else
                {
                    return string.Empty;
                }

            }
        }

        public int ChequeNumber
        {
            get
            {
                if (this.TransactionMasterChequeDetails.Count > 0) // can always be just one
                {
                    return this.TransactionMasterChequeDetails.FirstOrDefault().ChequeNumber;
                }
                else
                {
                    return 0;
                }

            }
        }

        public DateTime? ChequeDate
        {
            get
            {
                if (this.TransactionMasterChequeDetails.Count > 0) // can always be just one
                {
                    return this.TransactionMasterChequeDetails.FirstOrDefault().ChequeDate;
                }
                else
                {
                    return null;
                }

            }
        }

        private List<TransactionType> ArrangeItems(List<TransactionType> inputList)
        {
            List<TransactionType> temp = new List<TransactionType>();

            while (inputList.Count > 0)
            {
                temp.Add(GetRoot(inputList));
            }
            return temp;
        }

        private TransactionType GetRoot(List<TransactionType> inputList)
        {
            TransactionType root = inputList.Where(t => !inputList.Any(r => r.Id.Equals(t.ParentId))).Select(m => m).FirstOrDefault();
            inputList.Remove(root);
            return root;
        }
    }

    public partial class TransactionMasterChequeDetailsHistory
    {
        public string BankDisplayName
        {
            get
            {
                if (SettingsAndStaticListLoader.StaticListMap.ContainsKey(Constants.TableConstants.StaticListConstants.bankname))
                {
                    var bankNameValue = SettingsAndStaticListLoader.StaticListMap[Constants.TableConstants.StaticListConstants.bankname].
                                        Where(t => t.ListItemCode.Equals(this.ChequeDrawnOnBank)).FirstOrDefault();

                    if (bankNameValue != null)
                    {
                        return bankNameValue.ListItemValue;
                    }
                    else
                    {
                        return this.ChequeDrawnOnBank;
                    }
                }
                else
                {
                    return this.ChequeDrawnOnBank;
                }
            }
        }
    }

    public partial class ExpenseApprover
    {
        private string _displayName;
        public string DisplayName
        {
            get
            {
                this._displayName = this.FirstName + " " + this.LastName;
                return this._displayName;
            }
            set
            {
                this._displayName = value;
            }
        }
    }

    public partial class TransactionMasterHistory
    {
        public int VersionNumer { get; set; }

        public List<string> ChangeDetails
        {
            get
            {
                List<string> temp = new List<string>();
                int changedFields = this.ChangedFields;
                foreach (ChangedFields enumValue in Enum.GetValues(typeof(ChangedFields)))
                {
                    if ((changedFields & (int)enumValue) == (int)enumValue)
                    {
                        temp.Add(enumValue.ToString());
                    }
                }

                return temp;
            }
        }

        private List<TransactionType> GetTransactionTypes()
        {
            string[] idList = this.HeadDetailsHierarchyIdList.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

            List<int> transTypeIdList = new List<int>();
            foreach (string id in idList)
            {
                // CHECK THIS CHANGE
                string idWithoutBrackets = id.Replace("[", string.Empty).Replace("]", string.Empty).Trim();
                //transTypeIdList.Add(int.Parse(id));
                transTypeIdList.Add(int.Parse(idWithoutBrackets));
            }

            List<TransactionType> transactionTypeList = new DataAccessHandler().GetTransactionTypeListByIdList(transTypeIdList, new AlfaRomeoEntities());
            transactionTypeList = ArrangeItems(transactionTypeList);

            return transactionTypeList;
        }


        public string GetHeadDetailsComplete()
        {
            List<TransactionType> transactionTypeList = GetTransactionTypes();
            if (transactionTypeList.Count > 0)
            {
                transactionTypeList.RemoveAt(0);
                string headDetailsComplete = string.Join("-->", transactionTypeList.Select(t => t.Name).ToArray());
                return headDetailsComplete;
            }
            else
            {
                return string.Empty;
            }
        }

        public string GetConsolidatedChequeDetails()
        {
            string consolidatedDetails = string.Empty;

            string format = "No: {0}, Dated: {1}, {2}"; 
            List<string> temp = new List<string>();

            foreach (var transactionMasterChequeDetailsHistory in this.TransactionMasterChequeDetailsHistories)
            {
                temp.Add(string.Format(format, transactionMasterChequeDetailsHistory.ChequeNumber,
                                        transactionMasterChequeDetailsHistory.ChequeDate.Get_DD_MONTH_YY_DateString(),
                                        transactionMasterChequeDetailsHistory.BankDisplayName));
            }

            if (temp.Count > 0)
            {
                consolidatedDetails = string.Join(Environment.NewLine, temp.ToArray());
            }

            return consolidatedDetails;
        }


        public string ConsolidateChequeDetails
        {
            get
            {
                return GetConsolidatedChequeDetails();
            }
        }

        public string HeadDetailsDisplayName
        {
            get
            {
                return GetHeadDetailsComplete();
            }
        }

        public string TransactionDateDDMonthYY
        {
            get
            {
                return this.TransactionDate.Get_DD_MONTH_YY_DateString();
            }
        }

        public string HeadDisplayName
        {
            get
            {
                if (SettingsAndStaticListLoader.StaticListMap.ContainsKey(Constants.TableConstants.StaticListConstants.head))
                {
                    var headValue = SettingsAndStaticListLoader.StaticListMap[Constants.TableConstants.StaticListConstants.head].
                                        Where(t => t.ListItemCode.Equals(this.Head)).FirstOrDefault();

                    if (headValue != null)
                    {
                        return headValue.ListItemValue;
                    }
                    else
                    {
                        return this.Head;
                    }
                }
                else
                {
                    return this.Head;
                }
            }
        }

        public string TransactionModeValueDisplayName
        {
            get
            {
                if (SettingsAndStaticListLoader.StaticListMap.ContainsKey(Constants.TableConstants.StaticListConstants.transactionmode))
                {
                    var transactionMode = SettingsAndStaticListLoader.StaticListMap[Constants.TableConstants.StaticListConstants.transactionmode].
                                        Where(t => t.ListItemCode.Equals(this.TransactionModeValue)).FirstOrDefault();

                    if (transactionMode != null)
                    {
                        return transactionMode.ListItemValue;
                    }
                    else
                    {
                        return this.TransactionModeValue;
                    }
                }
                else
                {
                    return this.TransactionModeValue;
                }
            }
        }

        private List<TransactionType> ArrangeItems(List<TransactionType> inputList)
        {
            List<TransactionType> temp = new List<TransactionType>();

            while (inputList.Count > 0)
            {
                temp.Add(GetRoot(inputList));
            }
            return temp;
        }

        private TransactionType GetRoot(List<TransactionType> inputList)
        {
            TransactionType root = inputList.Where(t => !inputList.Any(r => r.Id.Equals(t.ParentId))).Select(m => m).FirstOrDefault();
            inputList.Remove(root);
            return root;
        }

        public string ExpenseApprovalDetails
        {
            get
            {
                string details = this.ExpenseApproverNames;
                if (string.IsNullOrEmpty(details))
                {
                    if (this.IsAutoApproved)
                    {
                        details = "Auto Approved";
                    }
                    else
                    {
                        details = "Approval not required";
                    }
                }
                return details;
            }
        }

        private string ExpenseApproverNames
        {
            get
            {
                string names = string.Empty;
                if (!string.IsNullOrEmpty(this.ExpenseApproverIdList))
                {
                    List<int> approverIdList = this.ExpenseApproverIdList.GetIntegerListFromSquareBracketedCommaSeparatedString();
                    if (approverIdList.Count == 0)
                    {
                        return string.Empty;
                    }
                    List<ExpenseApprover> requiredList = SettingsAndStaticListLoader.ExpenseApproverList.Where(t => approverIdList.Contains(t.Id)).ToList();
                    names = string.Join(", ", requiredList.Select(t => t.FirstName).ToArray());
                }
                return names;
            }
        }
    }

    public partial class TransactionType
    {
        public string HierarchyDisplayText
        {
            get;
            set;
        }

        private List<TransactionType> _parentHierarchyList = new List<TransactionType>();

        public List<TransactionType> ParentHierarchyList
        {
            get 
            { 
                return _parentHierarchyList; 
            }
        }

        public void LoadParentHierarchyList(AlfaRomeoEntities context)
        {
            if (_parentHierarchyList.Count > 0)
            {
                return;
            }
            List<TransactionType> temp = new List<TransactionType>();
            GetParentRecursively(this, temp, context);
            temp.Reverse();
            this._parentHierarchyList.AddRange(temp);
        }

        private void GetParentRecursively(TransactionType child, List<TransactionType> temp, AlfaRomeoEntities context)
        {
            if (child.ParentId < 0)
            {
                return;
            }
            TransactionType parent = context.TransactionTypes.Where(t => t.Id.Equals(child.ParentId)).FirstOrDefault();
            temp.Add(parent);
            GetParentRecursively(parent, temp, context);
        }
    }

    public partial class PettyCash
    {
        public void SetRollOverCountAndAmount(AlfaRomeoEntities context)
        {
            List<int> transactionMasterIdList = this.PettyCashUsages.Where(t => t.IsActive).Select(r => r.TransactionMasterId).ToList();
            bool anyRollOverTransaction = context.PettyCashUsages.Any(t => t.IsActive &&
                                               !t.PettyCashId.Equals(this.Id) &&
                                               transactionMasterIdList.Contains(t.TransactionMasterId));
            if (anyRollOverTransaction)
            {
                List<int> requiredDistinctTransactionMasterIdList = context.PettyCashUsages.Where(t => t.IsActive &&
                                               !t.PettyCashId.Equals(this.Id) &&
                                               transactionMasterIdList.Contains(t.TransactionMasterId)).Select(r => r.TransactionMasterId).Distinct().ToList();

                this._rollOverCount = requiredDistinctTransactionMasterIdList.Count();
                if (this._rollOverCount > 0) // should be ..why checking? :D
                {
                    decimal totalTransactionAmount = context.TransactionMasters.Where(t => t.IsActive &&
                                                                                           requiredDistinctTransactionMasterIdList.Contains(t.Id)).Sum(r => r.TransactionAmount);

                    decimal usedUpFromPettyCash = this.PettyCashUsages.Where(t => t.IsActive &&
                                                                                     requiredDistinctTransactionMasterIdList.Contains(t.TransactionMasterId)).Sum(r => r.UsedUpAmount);
                    this._rollOverAmount = totalTransactionAmount - usedUpFromPettyCash;
                }

            }
        }

        private int _rollOverCount;
        public int RollOverCount
        {
            get
            {
                return this._rollOverCount;
            }
        }

        public decimal _rollOverAmount;
        public decimal RollOverAmount
        {
            get
            {
                return this._rollOverAmount;
            }
        }
    }
}

